/* ----------------------------------------------------------------------------------------------------------------
 *  Renderer
 * ----------------------------------------------------------------------------------------------------------------
 */
package pure.engine.renderer 
{
	import flash.display.BitmapData;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import pure.engine.core.ITickListener;
	import pure.engine.core.ProcessManager;
	import pure.engine.core.VisibleCore;
	
	import pure.engine.core.ns_despair;
	use namespace ns_despair;
	
	/**
	 * 渲染器抽象类
	 * [Author] - PURE
	 * 
	 * [Feature] - 1. 由RendererCarrier创建
	 *             2. visible为false时，渲染器残像不会更新，动画停止
	 *             3. 表现真实存在的"不可见"物质，可将渲染器alpha设为接近0.
	 */
public class Renderer extends VisibleCore implements IRenderer
{

	
	
	
	//======================
	// Property
	//======================
	
	
	/**
	 * 透明度
	 */
	public function get alpha():Number
	{ 
		return m_alpha;
	}
	
	public function set alpha(v:Number):void 
	{
		if (m_alpha != v)
		{
			if      (v < 0)    m_alpha  =  0;
			else if (v > 1)    m_alpha  =  1;
			else               m_alpha  =  v
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}
	}
	

	/**
	 * 缩放x
	 */
	public function get scaleX():Number
	{ 
		return m_scaleX; 
	}
	
	public function set scaleX(v:Number):void 
	{
		if (v > 0 && m_scaleX != v)
		{
			m_scaleX = v;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}

	}
	
	
	/**
	 * 缩放y
	 */
	public function get scaleY():Number 
	{
		return m_scaleY;
	}
	
	public function set scaleY(v:Number):void
	{ 
		if (v > 0 && m_scaleY != v)
		{
			m_scaleY = v;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}

	}


	/**
	 * 缩放max
	 * 
	 * [Hint] - 普通情况，尽量不要使用该属性.
	 */
	public function get scaleMax():Number
	{
		return m_scaleMax; 
	}
	
	public function set scaleMax(v:Number):void
	{ 
		if (m_scaleMax != v)
		{
			m_scaleMax = v;
			if (m_dirtyFlag > -1)  m_dirtyFlag = 2;
		}
	}

	
	/**
	 * 是否可见
	 */
	override public function set visible(b:Boolean):void
	{
		if(m_visible != b)
		{
			m_dirtyFlag  =  Boolean(m_visible = b) ? 2 : -1;
		}
	}
	
	
	/**
	 * 弧度
	 */
	override public function set angle(v:Number):void 
	{ 
		if (m_angle != v)
		{
			m_angle = v;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}
	}
	
	
	/**
	 * 忽略弧度
	 */
	public function get ignoreAngle():Boolean
	{ 
		return m_ignoreAngle; 
	}
	
	public function set ignoreAngle(b:Boolean):void 
	{ 
		if (m_ignoreAngle != b)
		{
			m_ignoreAngle = b;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}
	}
	
	
	
	
	/* ----------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★★★★★★  private  ★★★★★★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------
	 */
	
	

	
	/**
	 * 更新
	 * 
	 * [Feature] ① visible为false(flag == -1)时，不做任何更新，除visible变化外，改变其他状态flag无效
	 *           ② 未变化，skip...visible为true时，初期值
	 *           ③ image变化，更新画像，visible为true时，可覆盖flag(0)
	 *           ④ range变化，会先检查一次，并更新画像，visible为true时，可覆盖flag(-1，0)
	 */
	ns_despair function advance(deltaTime:int):void 
	{
		var newRange:Number;
		var i:int;
		
		if (m_dirtyFlag <= 0)  return;
		
		// 一级画像缓存
		_generatePrimaryImage();
		
		// 范围变化
		if (m_dirtyFlag == 2)
		{
			if ((newRange = m_range * m_scaleMax) != m_oldRange)
			{
				if (m_alphaMask)
				{
					m_alphaMask.dispose();
					m_alphaMask = new BitmapData(m_imageB.width, m_imageB.height);
				}
				
				if (m_imageB)  m_imageB.dispose();
				
				m_imageB    =  new BitmapData(newRange * 2, newRange * 2, true, 0x0);
				m_oldRange  =  newRange;
			}
		}

		// 二级画像缓存
		m_imageB.fillRect(m_imageB.rect, 0x0);
		//m_imageB.fillRect(m_imageB.rect, 0x4000FF00);
		if (m_angle != 0 || m_scaleX != 1 || m_scaleY != 1)
		{
			cachedMatrix.identity();
			if (m_ignoreAngle)
			{
				cachedMatrix.rotate(-m_angle);
			}
			cachedMatrix.translate(m_x, m_y);
			cachedMatrix.scale(m_scaleX, m_scaleY);
			cachedMatrix.rotate(m_angle);
			cachedColorTransform.alphaMultiplier = m_alpha;
			cachedMatrix.translate(m_oldRange, m_oldRange);
			m_imageB.draw(m_imageA, cachedMatrix, cachedColorTransform, null, null, true);
		}
		
		else
		{
			cachedPoint.x  =  m_oldRange + m_x;
			cachedPoint.y  =  m_oldRange + m_y;
			
			if (m_alpha == 1) 
			{
				m_imageB.copyPixels(m_imageA, m_imageA.rect, cachedPoint, null, null, true);
			}
			else         
			{
				if (m_oldAlpha != m_alpha)
				{
					if (!m_alphaMask)
					{
						m_alphaMask = new BitmapData(m_imageB.width, m_imageB.height);
					}
					
					m_alphaMask.fillRect(m_alphaMask.rect, int(m_alpha * 255) << 24 | 0xFFFFFF);
					m_oldAlpha = m_alpha;
				}
				m_imageB.copyPixels(m_imageA, m_imageA.rect, cachedPoint, m_alphaMask, null, true);
			}
		}
		// 滤镜
		if (m_numFilter)
		{
			for (i = 0; i < m_numFilter; i++)
			{
				m_imageB.applyFilter(m_imageB, m_imageB.rect, cachedZeroPoint, m_filterList[i]);
			}
		}
		
	}

	
	// 毁灭
	override ns_despair function destroy():void
	{
		super.destroy();
		
		m_imageA = null;
		if (m_imageB)
		{
			m_imageB.dispose();
			m_imageB = null;
		}
		if (m_alphaMask)
		{
			m_alphaMask.dispose();
			m_alphaMask = null;
		}
	}
	

	/**
	 * [Overwrite]
	 * 生成一级画像缓存(m_imageA)
	 */
	protected function _generatePrimaryImage():void
	{
	}
	

	
	
	
	
	//======================
	// Member
	//======================
	

	ns_despair var m_alpha:Number = 1.0;  // 透明度

	ns_despair var m_oldAlpha:Number = 1.0;  // 记录了当前alphaMask的透明度

	ns_despair var m_scaleX:Number = 1.0;  // 缩放比X
	
	ns_despair var m_scaleY:Number = 1.0;  // 缩放比Y
	
	ns_despair var m_scaleMax:Number = 1.0;  // 最大缩放比(影响画像范围)

	ns_despair var m_alphaMask:BitmapData;  // copyPixels透明属性画像用.
	
	ns_despair var m_imageA:BitmapData;  // 一级画像缓存，未处理的原始画像数据缓存.

	ns_despair var m_imageB:BitmapData;  // 二级画像缓存，锁定实体中心的，处理过的输出画像.
	
	ns_despair var m_dirtyFlag:int = 2;
	

	
	
	
	//======================
	// Cached
	//======================

	
	ns_despair var cachedDuration:Number;
	
	ns_despair var m_oldRange:Number, m_position:Number;  // 记录了当前的
	
	ns_despair var m_ignoreAngle:Boolean;  // 旋转时是否忽略角度(保持原角度)

	ns_despair static var cachedMatrix:Matrix = new Matrix();
	
	ns_despair static var cachedColorTransform:ColorTransform = new ColorTransform();
	
	
}

}